package base.grammar; // 當前包

import java.util.ArrayList;
import java.util.List;

// 引用包
import base.grammar.test.AbstractTest;
import base.grammar.test.Interface1;
import base.grammar.test.Interface2;

// 继承及接口使用
// 类名与文件名相同
public class HelloWorld extends AbstractTest implements Interface1, Interface2{
	
	// 单行注释
	/*
	 * 多行注释
	 * */
	/***/
	
	// 常量
	public final String globalVar = "11111";  // 用final表示常量
	
	// 成员变量
	
	// 字符
	public char g = 'g'; // 基本类型
	
	// 字符串
	public String f = "sss";
	public String f1 = new String("");
	// public String f1 = new String(); //等价new String("");
	
	// 布尔类型
	public boolean h = false;
	public Boolean h1 = false;
	public Boolean h2 = new Boolean(true);
	
	// 成员变量需要先声明
	// f1 = new String("sss");
	
	// 數字類型
	private int a = 1; // 32位有符號整數 范围是-2147483648至2147483647(或-2^31至2^31-1)
	private Integer a1 = 1; // int 包裝類
	
	private long b = 1; // 64位有符號整數 范围是-9223372036854775808至9223372036854775807(或-2^63至2^63-1)
	private Long b1 = 1l; // long包裝類
	private long b2 = 1l; // 帶後綴“l”
	
	private short c = 1; // 16位有符號整數 范围是-32768至32767(或-2^15至2^15-1)
	private Short c1 = 1; // short包裝類
	
	private float d = 1.0f; // 單精度浮點數
	private Float d1 = 1f;
	private float d2 = 1;
	
	private double e = 1.0d; // 双精度浮點數
	private Double e1 = 1d; 
	private double e2 = 1; 
	
	private String s;
	/*getS*/
	public String getS() {
		return s;
	}
	// setS
	public void setS(String s) {
		this.s = s;
	}

	/** JavaDoc HelloWorld*/
	public HelloWorld(String s) {
		System.out.println(s);
		this.setS(s);
	}
	
	@Override
	public void run() {
		super.SuperFun();
		
		//this.a 基本类型不可以引用
		//this.a1 包装类可以引用已存在的方法
		
		// 定义局部变量，函数结束后销毁
		int localVar = 1;
		
		System.out.println("=====调用抽象方法=====");
		System.out.println(this.getA());
		System.out.println("=====调用实现接口方法=====");
		this.test1();
		this.test2();
	}
	
	// 实现接口Interface1的方法
	@Override
	public void test1() {
		// 死循环调用导致栈溢出
		// this.run(); // Exception in thread "main" java.lang.StackOverflowError
		
		System.out.println("test1:" + this.getA());
	}

	// 实现接口Interface2的方法
	@Override
	public void test2() {
		System.out.println("test2:" + this.getA());
	}

	// 重写同名覆盖父类方法
	public void OverwriteFun() {
		System.out.println("HelloWorld重写的方法");
	}
	
	// 重载同名不同参（因为方法参数不同导致方法签名不同）
	public void OverloadFun(String s) {
		System.out.println("HelloWorld重载的方法:" + s);
	}
	
	// Final 方法不能重写
	// public void RunFinal() {
		
	//}
	
	// Final方法可以重载
	public void RunFinal(String s) {
		System.out.println(s);
	}
	
	public void testFor() {
		System.out.println("=====For 循环=====");
		String[] arr = new String[10];
		for (int i=0; i<10; i++) {
			System.out.println("For:" + i);
			arr[i] = "i:" + i;
		}
		
		for(String s : arr) {
			if(s.equals("i:1"))
				continue;
			if(s.equals("i:5"))
				break;
			System.out.println(s);
		}
	}
	
	public void testDoWhile() {
		System.out.println("=====Do while循环=====");
		
		int i=-1;
		do {
			i += 1;
			System.out.println("do1:" + i);
		} while (i == 5);
		
		// 先做再判断
		i=-1;
		do {
			i += 1;
			System.out.println("do2:" + i);
		} while (i < 5);
	}
	
	public void testWhile() {
		System.out.println("=====while循环=====");
		int i=-1;
		while (i < 5) {
			i++;
			System.out.println("while:" + i);
		}
	}
	
	public void testIf() {
		System.out.println("=====if 判断=====");
		String[] arr = new String[10];
		for (int i=0; i<10; i++) {
			arr[i] = "i:" + i;
		}
		
		if (arr[0].equals("i:0")) {
			System.out.println("i:0 is ok.");
		} else if (arr[1].equals("i:1")) {
			System.out.println("i:1 is ok.");
		} 
		
		if(false){
			System.out.println("if false");
		}else {
			System.out.println("else section.");
		}
		
		if(arr instanceof String[]) 
			System.out.println("arr instanceof String[]");
		
		if(arr instanceof String[]) {
			System.out.println("if return");
			return;
		}
		
		System.out.println("the end.");
	}
	
	public void testSwitch() {
		System.out.println("=====switch 判断=====");
		
		String s = "123";
		switch (s) {
			case "123":
				System.out.println("switch s=123 1");
				System.out.println("switch s=123 2");
				
		}
		
		switch (s) {
			case "xxx":
				System.out.println("switch xxx");
			case "123":
				System.out.println("switch 123 1");
			//case "123": // 不允許出現相同的值
				//System.out.println("switch 123 1");
		}
		
		switch (s) {
			case "xxx":
				System.out.println("switch xxx");
			default:
				System.out.println("switch default");
		}
	}
	
	public void testEception() {
		try {
			testException1();
		} catch (MyException e) {
			System.out.println("抓到了MyException异常：" + e.getMessage());
		} catch (Exception e) {
			System.out.println("抓到了Exception异常：" + e.getMessage());
			e.printStackTrace();
		} finally {
			System.out.println("是否有异常都会执行。");
		}
	}

	public void testException1() throws Exception, MyException {
		throw new MyException("抛出了异常");
	}
	
	// 内部类
	class MyException extends Exception{

		public MyException(String string) {
			super(string);
		}
		
	}
	
	public void testReference() {
		
		System.out.println("基本类型及基本类型的包装类作为函数的参数是对传入数据的copy。");
		int i1 = 1;
		this.testRef1(i1);
		Integer i2 = 1;
		this.testRef2(i2);
		Integer i3 = new Integer(1);
		this.testRef3(i3);
		System.out.println("int i1：" + i1);
		System.out.println("Integer i2：" + i2);
		System.out.println("new Integer i3：" + i3);
		
		System.out.println("其他对象作为参数传入函数，相当于对象的引用。");
		List<String> list = new ArrayList<String>();
		list.add("1");
		System.out.println("传入函数前的list size：" + list.size());
		this.testRef4(list);
		System.out.println("传入函数后的list size：" + list.size());
	}
	
	public void testRef1(int i) {
		i += 1;
	}
	
	public void testRef2(Integer i) {
		i += 1;
	}
	
	public void testRef3(Integer i) {
		i += 1;
	}
	
	public void testRef4(List<String> list) {
		list.add("2");
	}
	
	// 主程序入口
	public static void main(String[] args) throws MyException {
		
		System.out.println("Hello World!");
		
		System.out.println("======类的初始化=====");
		HelloWorld h = new HelloWorld("初始化构造方法");
		System.out.println("调用开放成员：" + h.f1.equals(""));
		System.out.println("调用开放方法：" + h.getS());
		
		System.out.println("======类的初始化=====");
		h.setA("abc"); // 使用父类方法
		h.run(); // 运行实现的抽象方法
		
		System.out.println("======final 及 static 的使用=====");
		System.out.println(HelloWorld.F_STR); // 静态方法中可以直接调用静态变量
		System.out.println(h.F_STR);
		System.out.println(h.fStr);
		h.RunFinal("重载的Final方法");
		// 静态方法调用
		HelloWorld.RunStatic();
		AbstractTest.RunStatic();
		// h.fStr = "sss"; // final 修饰不允许修改
		
		System.out.println("======重写=====");
		h.OverwriteFun();
		
		System.out.println("======重载=====");
		h.OverloadFun();
		h.OverloadFun(F_STR);
		
		System.out.println("=====程序控制语句=====");
		h.testFor();
		h.testDoWhile();
		h.testWhile();
		h.testIf();
		h.testSwitch();
		
		System.out.println("=====引用参数实现=====");
		h.testReference();
		
		int i = 5;
		int j = 3;
		String si = Integer.toBinaryString(i);
		String sj = Integer.toBinaryString(j);
		System.out.println(si + ", " + sj);
		
		System.out.println("===逻辑运算===");
		int k = i & j;
		System.out.println("k:" + Integer.toBinaryString(k));
		k = i | j;
		System.out.println("k:" + Integer.toBinaryString(k));
		k = ~i;
		System.out.println("k:" + Integer.toBinaryString(k));
		k = i ^ j;
		System.out.println("k:" + Integer.toBinaryString(k));
		
		System.out.println("=====异常捕获=====");
		h.testEception();
	}
}
